//Kiosk 64
//Version IR#
//(C) Night-Eagle 2007

include("shared.lua")
include("cl_hack.lua")

local tex = {
	corner = surface.GetTextureID("client/quarter256"),
}

local dims
do
	local s = 30
	dims = {
		x = -10.5*s,
		y = -24.7*s,
		w = 21*s,
		h = 16.1*s,
		s = s
	}
end

local ScrW = function()
	return dims.w
end

local ScrH = function()
	return dims.h
end

function ENT:Initialize()
	self.mc = {}
	self.key = {mod={},last=CurTime()}
	for i = 0,4 do
		self.mc[i] = {
			click=0,
			uid=nil,
			data=nil,
		}
	end
	self.uid = 0
	self.desklight = 0
	//hack.LoadData()
	
	self.windowmeta = {
			caption = "Untitled Window",
			x = 0,
			y = 0,
			w = 0,
			h = 0,
			key = -1,
			visible = true,
			data = {},
			options = {},
			DrawWindowPre = function(window)
				//Msg("DEBUG: Called ",CurTime(),"\n")
				local focus = false
				if hack.focus[1] == window.key then
					if hack.focus[2] == "" then
						focus = true
					end
					self.desklight = window.key
				end
				local s = hack.scheme
				local b = s.border
				local count = 0
				
				if window.options.close then
					count = count+1
				end
				if window.options.minimize then
					count = count+1
				end
				
				local caption = window.caption
				surface.SetFont("Trebuchet18")
				do
					local caplen = surface.GetTextSize(caption)
					local space = window.w-(count+1)*s.border*2-s.border*1
					if space < caplen then
						space = space-s.border*2
						caption = string.sub(caption,1,math.floor(space/caplen*#caption)-#caption).."..."
					end
				end
				
				local capsize = surface.GetTextSize(caption)
				
				local color
				if hack.focus[1] == window.key or self.desklight == window.key then
					//if hack.mouse then //Desktop Removal
						color = s.c3
					//else //Desktop Removal
					//	color = s.c1 //Desktop Removal
					//end //Desktop Removal
				else
					color = s.c1
				end
				
				surface.SetTexture(tex.corner)
				
				//Collision Checks
				
				local col = {}
				do
					col[1] = s.f1
					if focus and
						window.mx > window.w-b*2 and
						window.mx < window.w-4 and
						window.my > -b*2 and
						window.my < 0
					then
						focus = false
						col[1] = s.f2
						if self.mc[0].click == 2 and self.mc[0].uid == window.uid and self.mc[0].data and self.mc[0].data.type == "close" then
							col[1] = s.f3
						end
						
						if self.mc[0].click == 1 then
							self.mc[0].click = 2
							self.mc[0].uid = window.uid
							self.mc[0].data = {
								type = "close",
							}
						end
					end
					col[2] = s.f1
					if focus and
						window.mx > window.w-b*4 and
						window.mx < window.w-b*2-4 and
						window.my > -b*2 and
						window.my < 0
					then
						focus = false
						col[2] = s.f4
						if self.mc[0].click == 2 and self.mc[0].uid == window.uid and self.mc[0].data and self.mc[0].data.type == "minimize" then
							col[2] = s.f3
						end
						
						if self.mc[0].click == 1 then
							self.mc[0].click = 2
							self.mc[0].uid = window.uid
							self.mc[0].data = {
								type = "minimize",
							}
						end
					end
					
					//Resize
					col[3] = color
					if window.options.resize and focus and
						window.mx > window.w and
						window.mx < window.w+b and
						window.my > window.h and
						window.my < window.h+b
					then
						focus = false
						col[3] = s.c4
						if self.mc[0].click == 2 and self.mc[0].uid == window.uid and self.mc[0].data and self.mc[0].data.type == "minimize" then
							col[3] = s.c5
						end
						
						if self.mc[0].click == 1 then
							self.mc[0].click = 2
							self.mc[0].uid = window.uid
							self.mc[0].data = {
								type = "resize",
								x = window.mx-window.w,
								y = window.my-window.h,
							}
						end
					end
				end
				
				//Close and minimize
				if hack.focus[1] == window.key and
					hack.focus[2] == "" and
					window.mx > window.w-b*2 and
					window.mx < window.w-4 and
					window.my > -b*2 and
					window.my < 0 and
					self.mc[0].click == -1 and
					self.mc[0].uid == window.uid and
					self.mc[0].data.type == "close"
				then
					window:close() //self.mc is cleared by closing, so no need to clear.
					return
				end	
				if hack.focus[1] == window.key and
					hack.focus[2] == "" and
					window.mx > window.w-b*4 and
					window.mx < window.w*2-4 and
					window.my > -b*2 and
					window.my < 0 and
					self.mc[0].click == -1 and
					self.mc[0].uid == window.uid and
					self.mc[0].data.type == "minimize"
				then
					self.mc[0] = { //ALWAYS clear the self.mc table in this fashion when finished!
						click = 0,
						uid = nil,
						data = nil,
					}
					window:minimize()
				end
				
				//Movement and context menu
				//if self.mc[0].data then
					//Msg(CurTime(),"\n")
				//end
				if focus and
					window.my < 0
				then
					focus = nil
					
					if self.mc[0].click == 1 then
						self.mc[0].click = 2
						self.mc[0].uid = window.uid
						self.mc[0].data = {
							type = "drag",
							x = window.mx,
							y = window.my,
						}
						//Msg(CurTime(),"\n\tSet to ",window.mx,", ",window.my,"\n")
					end
					if self.mc[1].click == 1 then
						self.mc[1].click = 2
						self.mc[1].uid = window.uid
						self.mc[1].data = {
							type = "context",
						}
					end
				end
				
				--'
				--' WARNING: These seem to be called twice per frame, investigate NOW
				--'
				
				//Movement
				if self.mc[0].uid == window.uid and self.mc[0].data and self.mc[0].data.type == "drag" then
					if self.mc[0].click == 2 then
						//Msg("\tMoved to: ",self.mc.x-self.mc[0].data.x,", ",self.mc.x-self.mc[0].data.y,"\n\tWindow: ",window.mx,", ",window.my,"\n")
						window.x = self.mc.x-self.mc[0].data.x
						window.y = self.mc.y-self.mc[0].data.y
					elseif self.mc[0].click == -1 then
						//window.x = self.mc.x-self.mc[0].data.x
						//window.y = self.mc.y-self.mc[0].data.y
						self.mc[0] = { //ALWAYS clear the self.mc table in this fashion when finished!
							click = 0,
							uid = nil,
							data = nil,
						}
					end
				end
				//Resize
				if self.mc[0].uid == window.uid and self.mc[0].data and self.mc[0].data.type == "resize" then
					if self.mc[0].click == 2 then
						window.w = math.max(self.mc.x-window.x-self.mc[0].data.x,
							tonumber(window.minw) or (count+1)*s.border*2+50)
						window.h = math.max(self.mc.y-window.y-self.mc[0].data.y,tonumber(window.minh) or 0)
					elseif self.mc[0].click == -1 then
						//window.w = math.max(self.mc.x-window.x-self.mc[0].data.x,
						//	tonumber(window.minw) or (count+1)*s.border*2+50)
						//window.h = math.max(self.mc.y-window.y-self.mc[0].data.y,tonumber(window.minh) or 0)
						self.mc[0] = { //ALWAYS clear the self.mc table in this fashion when finished!
							click = 0,
							uid = nil,
							data = nil,
						}
					end
				end
				//Context
				if hack.focus[1] == window.key and
					hack.focus[2] == "" and
					self.mc[1].click == -1 and
					self.mc[1].uid == window.uid and
					self.mc[1].data.type == "context"
				then
					self.mc[1].click = 0
					self.mc[1].uid = nil
					self.mc[1].data = nil
					
					window.context = {
						x = window.mx,
						y = window.my,
					}
				end
				
				//Begin drawing
				if count > 0 then
					window:DrawTexturedRect(window.w-b,0,b*4,b*4,color,0)
					window:DrawTexturedRect(window.w-b*count*2,-b,b*2,b*2,nil,90)
				else
					window:DrawTexturedRect(window.w,0,b*2,b*2,color,0)
				end
				
				window:DrawRect(b,-b*2,capsize,b)
				window:DrawTexturedRect(b+capsize,-b,b*2,b*2,nil,0)
				window:DrawTexturedRect(b,0,b*4,b*4,nil,90)
				
				window:DrawTexturedRect(0,window.h,b*2,b*2,nil,180)
				window:DrawTexturedRect(window.w,window.h,b*2,b*2,col[3],270)
				window:DrawRect(b,-b,window.w-b*count*2-b,b,color) //Recolored because of col[3]
				window:DrawRect(0,window.h,window.w,b)
				window:DrawRect(-b,0,b,window.h)
				window:DrawRect(window.w,0,b,window.h)
				if center then
					window:DrawRect(0,0,window.w,window.h)
				end
				window:DrawRect(window.w-b*count*2,-b*2,b*count*2-b,b*2)
				
				if window.options.close then
					color = col[1]
					
					window:DrawText("x","Trebuchet24",window.w-4,-b*2-6,color,2)
					if window.options.minimize then
						color = col[2]
						
						window:DrawText("_","Trebuchet24",window.w-20,-b*2-9,color,2)
					end
				elseif window.options.minimize then
					color = col[1]
					
					window:DrawText("_","Trebuchet24",window.w-4,-b*2-9,color,2)
				end
				
				window:DrawText(caption,"Trebuchet18",9,-b*2-1,s.f1,0)
				
				window:DrawRect(0,0,window.w,window.h,s.c2)
				
				//We do not set hack.focus[1] = -1 here because if the frame is being used, it should not be drawn over anyway. hack.focus[1] = -1 tells all forms that they are not receiving input (Mouse hovers, clicks, etc.)
			end,
			DrawWindowPost = function(window)
				//Context menu
				if window.context then
					local args = {
						x = window.context.x,
						y = window.context.y,
						items = {},
					}
					if window.options.minimize then
						table.insert(args.items,{
							label = "Minimize",
							enabled = true
						})
					end
					if window.options.close then
						table.insert(args.items,{
							label = "Close",
							enabled = true
						})
					end
					
					local ret = window:DrawMacro(0,"contextmenu",args)
					if type(ret) == "table" then
						if args.items[ret[1]] then
							window.context = nil
							local label = args.items[ret[1]].label
							if label == "Minimize" then
								window:minimize()
							elseif label == "Close" then
								window:close()
							end
						end
					end
					
					if
						(self.mc[0].click == 1 and type(self.mc[0].data) ~= "table") or
						(self.mc[1].click == 1 and type(self.mc[1].data) ~= "table")
					then
						window.context = nil
					end
				end
			end,
			DrawText = function(window,text,font,x,y,color,xalign)
				draw.DrawText(text,font,dims.x+window.x+x,dims.y+window.y+y,color,xalign)
			end,
			DrawRect = function(window,x,y,w,h,color)
				if color then
					surface.SetDrawColor(color.r,color.g,color.b,color.a)
				end
				surface.DrawRect(dims.x+window.x+x,dims.y+window.y+y,w,h)
			end,
			DrawTexturedRect = function(window,x,y,w,h,color,rot)
				if color then
					surface.SetDrawColor(color.r,color.g,color.b,color.a)
				end
				if not rot then
					surface.DrawTexturedRect(dims.x+window.x+x,dims.y+window.y+y,w,h)
				else
					surface.DrawTexturedRectRotated(dims.x+window.x+x,dims.y+window.y+y,w,h,rot)
				end
			end,
			DrawRoundedRect = function(window,x,y,w,h,b,bcol,center)
				surface.SetTexture(tex.corner)
				window:DrawTexturedRect(x+w,y,b*2,b*2,bcol,0)
				window:DrawTexturedRect(x,y,b*2,b*2,nil,90)
				window:DrawTexturedRect(x,y+h,b*2,b*2,nil,180)
				window:DrawTexturedRect(x+w,y+h,b*2,b*2,nil,270)
				window:DrawRect(x,y-b,w,b)
				window:DrawRect(x,y+h,w,b)
				window:DrawRect(x-b,y,b,h)
				window:DrawRect(x+w,y,b,h)
				if center then
					window:DrawRect(x,y,w,h)
				end
			end,
			DrawForm = function(window,name,type,args)
				for k,v in pairs(hack.forms[type]) do
					if args[k] == nil then
						args[k] = v
					end
				end
				return hack.forms[type].draw(args,window,name,self)
			end,
			DrawMacro = function(window,name,type,args)
				for k,v in pairs(hack.macros[type]) do
					if args[k] == nil then
						args[k] = v
					end
				end
				return hack.macros[type].draw(args,window,name,self)
			end,
			bounds = function(window)
				if window.visible then
					local b = hack.scheme.border
					local ret = {
							{
								window.x-b,
								window.y-b*2,
								window.x+window.w+b,
								window.y+window.h+b,
							},
						}
					return ret
				else
					return {}
				end
			end,
			close = function(window,nomcreset)
				table.remove(self.windows,window.key)
				if not nomcreset then
					for i = 0,4 do
						self.mc[i] = {
							click=0,
							uid=nil,
							data=nil,
							}
					end
				end
			end,
			minimize = function(window)
				window.visible = false
			end,
		}
	
	self.windows = {
			{
				caption = "Kiosk Operating System - Welcome",
				options = {
						close = true,
						minimize = true,
					},
				x = ScrW()*.5 - 128,
				y = ScrH()*.5 - 64,
				w = 256,
				h = 128,
				draw = function(self)
					if not self.visible then //The draw function will still be called even if your window is minimized, so check to see if it is minimized first.
						return
					end
					local s = hack.scheme
					self:DrawWindowPre()
					
					self:DrawText("Welcome to the Kiosk Operating System!\n\nI hope you enjoy the new interface\nupgrades and improved usability of this\nversion.","Trebuchet18",4,4,s.f1)
					self:DrawText("(C) Night-Eagle 2007","Trebuchet18",self.w-4,self.h-20,s.f1,2)
					
					//hack.focus[1] = -1 //If this was uncommented, the button below could never be clicked or highlighted, keep this in mind.
					//IMPORTANT: You should ONLY set this to -1 if hack.focus[1] == self.focus.
					//hack.focus[1] holds the key of the window that should receive mouse clicks.
					//(Note - When a window is clicked, its key is set to 1 - this due to the draw order algorithm.)
					
					//When using the "button" type form, it returns -1 for release-clicked, nil for not clicked, 1 for start-clicked, and 2 for hold-clicked.
					//You typically only want to execute code when self:DrawForm returns a -1 (Negative 1).
					//If you execute code when it is positive 1, then you are not letting the user release the button.
					if self:DrawForm("button1","button",{
						x = 8,
						y = self.h-26,
						w = 32,
						h = 18,
						label = "OK",
						}) == -1
					then
						self:close()
					end
					self:DrawWindowPost()
				end,
			},
		}
	
	
	self.windows[0] = {
		caption = "Desktop",
		options = {
				close = false,
				minimize = false,
			},
		x = 0,
		y = 0,
		w = ScrW(),
		h = ScrH(),
		draw = function(window)
			local s = hack.scheme
			//local GM = _G.hack //Desktop removal (Monitor)
			local GM = self
			
			window:DrawText("Desktop","Trebuchet24",8,4,s.f1)
			
			local wins = GM.windows
			local passed = false
			for i=1,#wins do
				local col = s.c1
				local fcol = s.f1
				local clop = false
				local toclose = false
				
				//Collision check
				//Close
				if hack.focus[1] == window.key and
					hack.focus[2] == "" and
					window.mx > 12 and
					window.mx < 28 and
					window.my > ScrH()-22*i and
					window.my < ScrH()-22*i+18
				then
					fcol = s.f2
					clop = true
					
					if self.mc[0].click == 1 then
						self.mc[0].click = 2
						self.mc[0].uid = window.uid
						self.mc[0].data = {
							type = "close",
							key = i,
							}
					elseif
						self.mc[0].uid == window.uid and
						self.mc[0].data and
						self.mc[0].data.key == i and
						self.mc[0].data.type == "close"
					then
						if self.mc[0].click == 2 then
							fcol = s.f3
						elseif self.mc[0].click == -1 then
							self.mc[0].click = 0
							self.mc[0].uid = nil
							self.mc[0].data = nil
							
							toclose = true
						end
					end
				end
				
				//Open
				if hack.focus[1] == window.key and
					hack.focus[2] == "" and
					window.mx > 8 and
					window.mx < 256 and
					window.my > ScrH()-22*i and
					window.my < ScrH()-22*i+18
				then
					self.desklight = i
					col = s.c3
					passed = true
					if (not clop) and self.mc[0].click == 1 then
						self.mc[0].click = 2
						self.mc[0].uid = window.uid
						self.mc[0].data = {
							type = "open",
							key = i,
							}
					elseif
						self.mc[0].uid == window.uid and
						self.mc[0].data and
						self.mc[0].data.key == i and
						self.mc[0].data.type == "open"
					then
						if self.mc[0].click == 2 then
							col = s.c4
						elseif self.mc[0].click == -1 then
							self.mc[0].click = 0
							self.mc[0].uid = nil
							self.mc[0].data = nil
							
							local temp = GM.windows[i]
							for j=i,2,-1 do
								GM.windows[j] = GM.windows[j-1]
							end
							GM.windows[1] = temp
							
							GM.windows[1].visible = true
						end
					end
				elseif self.desklight == i and GM.windows[i].visible then
					col = s.c3
				end
				
				//Draw
				window:DrawRoundedRect(
					16,
					ScrH()-22*i+8,
					232,
					2,
					8,col,true
				)
				window:DrawText(
					tostring(wins[i].caption),
					"Trebuchet18",
					40,
					ScrH()-22*i,
					s.f1,0
				)
				window:DrawText(
					"x",
					"Trebuchet24",
					16,
					ScrH()-22*i-5,
					fcol,0
				)
				
				if toclose then
					wins[i]:close()
					break
				end
			end
			
			if not passed then
				self.desklight = 1
				
				//Context menu
				if self.mc[1].click == 1 and hack.focus[1] == window.key then
					//self.mc[1].click = 2
					local window = {
						caption = "Context Menu",
						options = {
								close = false,
								minimize = false,
							},
						x = self.mc.x,//Desktop removal (self.mx) //Warning
						y = self.mc.y,//Desktop removal
						w = 0,
						h = 0,
						draw = function(window)
							if not window.visible then
								return
							end
							
							//Close on de-focus
							
							if
								window.key ~= 1 or
								(hack.focus[1] ~= window.key and self.mc[0].click == 1)
							then
								window:close()
							end
							
							local contextmenu = {
								items = {
									{
										label = "New Process",
										enabled = true,
										list = true,
									},
									{
										label = "Restore Process",
										enabled = true,
										list = true,
										w = 228,
									},
									{
										label = "Cut",
										enabled = false,
									},
									{
										label = "Copy",
										enabled = false,
									},
									{
										label = "Paste",
										enabled = false,
									},
								},
							}
							
							local wins = GM.apps
							for i=1,#wins do
								local item = {
									label = wins[i].label,
									enabled = true,
									list = true,
								}
								for o = 1,#wins[i] do
									table.insert(item,{
										label = wins[i][o].caption,
										enabled = true,
									})
								end
								table.insert(contextmenu.items[1],item)
							end
							
							local wins = GM.windows
							for i=1,#wins do
								local item = {
									label = wins[i].caption,
									enabled = not wins[i].visible,
								}
								if wins[i].visible == "temp" then
									item.enabled = true
								end
								table.insert(contextmenu.items[2],item)
								
								//While we are at it, hide all temporarily visible windows
								if wins[i].visible == "temp" then
									wins[i].visible = false
								end
							end
							
							local ret = window:DrawMacro(0,"contextmenu",contextmenu)
							
							if ret == -1 then
								window:close()
							elseif ret[1] == 1 then
								//Create new window
								if ret[2] and ret[3] then
									table.insert(GM.windows,1,hack.InitWindow(self,GM.apps[ret[2]][ret[3]]))
									GM.windows[1].x = window.x
									GM.windows[1].y = window.y
								end
							elseif ret[1] == 2 then
								//Restore old window
								if ret[2] then
									local i = ret[2]
									local temp = GM.windows[i]
									for j=i,2,-1 do
										GM.windows[j] = GM.windows[j-1]
									end
									GM.windows[1] = temp
									
									GM.windows[1].visible = true
									
									for i=1,#wins do
										if wins[i].visible == "temp" then
											wins[i].visible = false
										end
									end
								elseif ret[1] and ret[3] then
									GM.windows[ret[3]].visible = "temp"
								end
							end
						end,
						bounds = function(self)
							
							if self.visible then
								local b = hack.scheme.border
								local ret = {
										{
											self.x,
											self.y,
											self.x+self.w,
											self.y+self.h,
										},
									}
								return ret
							else
								return {}
							end
							//Desktop removal
							//return {} //Desktop removal
						end
					}
					table.insert(GM.windows,1,hack.InitWindow(self,window))
				end
				//Context menu end, see draw function for update
			end
		end,
	}
	
	self.windows[0] = hack.InitWindow(self,self.windows[0]) //Desktop removal
	//self.windows[0] = nil //Desktop removal
	self.windows[1] = hack.InitWindow(self,self.windows[1])
	//self.windows[2] = hack.InitWindow(self,self.windows[2])
	
	self.apps = {}
	
	//Load apps from files
	if debugmode then
		Msg("Loading computer apps...\n")
	end
	for k,v in pairs(file.FindInLua("entities/computer64/apps/*.lua")) do //Desktop Removal
		if debugmode then
			Msg("Processing ",v,"\n")
		end
		include("entities/computer64/apps/"..v) //Desktop Removal
		if debugmode then
			Msg("\t",app,"\n")
		end
		if
			type(app) == "table" and
			type(app.folder) == "table" and
			type(app.app) == "table" and
			type(app.app.caption) == "string" and
			type(app.app.draw) == "function" and
			type(app.app.bounds or app.app.draw) == "function"
		then
			if debugmode then
				Msg("\tPassed application verification.\n")
			end
			local fail = false
			
			for k,v in ipairs(app.folder) do
				if type(v) ~= "string" then
					if debugmode then
						Msg("Invalid folder.","\n")
					end
					fail = true
				end
			end
			
			for k,v in ipairs(app.app.options or {}) do
				if type(v) ~= "string" then
					if debugmode then
						Msg("Invalid window options table.","\n")
					end
					fail = true
				end
			end
			
			for k,v in pairs({"x","y"}) do
				if type(app.app[v] or 0) ~= "number" then
					if debugmode then
						Msg("Invalid ",v," coordinate.","\n")
					end
					fail = true
				end
			end
			
			for k,v in pairs({"w","h"}) do
				if type(app.app[v]) ~= "number" then
					if debugmode then
						Msg("Invalid ",v," value.","\n")
					end
					fail = true
				end
			end
			
			app.app.key = nil
			
			if not fail then
				//The application seems valid, let's load it!
				if debugmode then
					Msg("\tSuccess, saving ",app.app.caption,"!\n")
				end
				
				local apptable = self.apps
				for i = 1, #app.folder do
					local notfound = true
					for k,v in pairs(apptable) do
						if v.label == app.folder[i] then
							apptable = apptable[k]
							notfound = false
							if debugmode then
								Msg("\t\tFound folder ",app.folder[i],".\n")
							end
						end
					end
					if notfound then
						local newtable = {
							label = app.folder[i]
						}
						table.insert(apptable,newtable)
						apptable = apptable[#apptable]
						if debugmode then
							Msg("\t\tCreated folder ",app.folder[i],".\n")
						end
					end
				end
				if debugmode then
					Msg("\tSaved as: ")
					for k,v in pairs(app.folder) do
						Msg(v,"\\")
					end
					Msg(app.app.caption,"\n")
				end
				table.insert(apptable,app.app)
			end
		else
			if debugmode then
				Msg("\tFailed application verification.\n")
			end
		end
		
		app = nil
	end
end

--"

--"

--"

--"

--"

--"

--"

--"

--"

--"

function ENT:Draw()
	//Clicking
	
	//End clicking
	
	
	self.Entity:DrawModel()
	
	/*
	self.x1 = -10.5
	self.x2 = 10.5
	self.y1 = 24.7
	self.y2 = 8.6
	self.z = 3.33
	self.mz = self.z
	*/
	
	local ang = self.Entity:GetAngles()
	local rot = Vector(-90,90,0)
	ang:RotateAroundAxis(ang:Right(),rot.x)
	ang:RotateAroundAxis(ang:Up(),rot.y)
	//ang:RotateAroundAxis(ang:Forward(),rot.z)
	
	local pos = self.Entity:GetPos()+(self.Entity:GetForward()*3.33)
	
	//Calculate mouse
	local trace = {}
		trace.start = LocalPlayer():GetShootPos()
		trace.endpos = LocalPlayer():GetCursorAimVector()*64+trace.start
		trace.filter = LocalPlayer()
	local trace = util.TraceLine(trace)
	
	if trace.Entity == self.Entity then
		self.control = true
		hack.control = self:EntIndex()
		local pos = self.Entity:WorldToLocal(trace.HitPos)
		
		self.mc.x = (pos.y-dims.x/dims.s)*dims.s
		self.mc.y = (pos.z+dims.y/dims.s)*-dims.s
	end
	if trace.Entity ~= self.Entity or self.mc.x > dims.w or self.mc.y > dims.h or self.mc.x < 0 or self.mc.y < 0 then
		self.control = false
		self.mc.x = dims.w*.5
		self.mc.y = dims.h*.5
	end
	//Stop calculating mouse
	
	cam.Start3D2D(pos,ang,1/dims.s)
		surface.SetDrawColor(0,0,0,255)
		surface.DrawRect(dims.x,dims.y,dims.w,dims.h)
		
		//self.mc.x,self.mc.y = gui.MousePos()
		hack.focus = hack.GetFocus(self)
		
		//Refocusing
		if (self.mc[0].click == 1 or self.mc[1].click == 1) and hack.focus[1] ~= 0 and hack.focus[1] ~= 1 then
			local temp = self.windows[hack.focus[1]]
			for i=hack.focus[1],2,-1 do
				self.windows[i] = self.windows[i-1]
			end
			self.windows[1] = temp
		end
		//End refocusing
		
		hack.focus = hack.GetFocus(self)
		
		//Black-out
		//surface.SetDrawColor(0,0,0,255)
		//surface.DrawRect(0,0,ScrW(),ScrH())
		
		//for k,window in ipairs(self.windows) do //Warning
		//Desktop removal
		do
			local k = 0
			local window = self.windows[k]
			self.windows[k].key = k
			self.windows[k].mx = self.mc.x-window.x
			self.windows[k].my = self.mc.y-window.y
			self.windows[k].mc = self.mc
			self.windows[k].macrobounds = nil
			window:draw()
		end
		
		for k = #self.windows,1,-1 do
			local window = self.windows[k]
			self.windows[k].key = k
			self.windows[k].mx = self.mc.x-window.x
			self.windows[k].my = self.mc.y-window.y
			self.windows[k].mc = self.mc
			self.windows[k].macrobounds = nil
			window:draw()
		end
		
		//Desktop removal substitute
		/*
		do
			local GM = self
			//Context menu
			if self.mc[1].click == 1 and hack.focus[1] == 0 then //Desktop removal ( == 1 to == 0 ) //Warning
				//self.mc[1].click = 2
				local window = {
						caption = "Context Menu",
						options = {
								close = false,
								minimize = false,
							},
						x = self.mc.x,//Desktop removal (self.mx) //Warning
						y = self.mc.y,//Desktop removal
						w = 0,
						h = 0,
						draw = function(window)
							if not window.visible then
								return
							end
							
							//Close on de-focus
							
							if
								window.key ~= 1 or
								(hack.focus[1] ~= window.key and self.mc[0].click == 1)
							then
								window:close()
							end
							
							local contextmenu = {
								items = {
									{
										label = "New Process",
										enabled = true,
										list = true,
									},
									{
										label = "Restore Process",
										enabled = true,
										list = true,
										w = 228,
									},
									{
										label = "Cut",
										enabled = false,
									},
									{
										label = "Copy",
										enabled = false,
									},
									{
										label = "Paste",
										enabled = false,
									},
								},
							}
							
							local wins = GM.apps
							for i=1,#wins do
								local item = {
									label = wins[i].label,
									enabled = true,
									list = true,
								}
								for o = 1,#wins[i] do
									table.insert(item,{
										label = wins[i][o].caption,
										enabled = true,
									})
								end
								table.insert(contextmenu.items[1],item)
							end
							
							local wins = GM.windows
							for i=1,#wins do
								local item = {
									label = wins[i].caption,
									enabled = not wins[i].visible,
								}
								if wins[i].visible == "temp" then
									item.enabled = true
								end
								table.insert(contextmenu.items[2],item)
								
								//While we are at it, hide all temporarily visible windows
								if wins[i].visible == "temp" then
									wins[i].visible = false
								end
							end
							
							local ret = window:DrawMacro(0,"contextmenu",contextmenu)
							
							if ret == -1 then
								window:close()
							elseif ret[1] == 1 then
								//Create new window
								if ret[2] and ret[3] then
									table.insert(GM.windows,1,hack.InitWindow(self,GM.apps[ret[2]][ret[3]]))
									GM.windows[1].x = window.x
									GM.windows[1].y = window.y
								end
							elseif ret[1] == 2 then
								//Restore old window
								if ret[2] then
									local i = ret[2]
									local temp = GM.windows[i]
									for j=i,2,-1 do
										GM.windows[j] = GM.windows[j-1]
									end
									GM.windows[1] = temp
									
									GM.windows[1].visible = true
									
									for i=1,#wins do
										if wins[i].visible == "temp" then
											wins[i].visible = false
										end
									end
								elseif ret[1] and ret[3] then
									GM.windows[ret[3]].visible = "temp"
								end
							end
						end,
						bounds = function(self)
							
							if self.visible then
								local b = hack.scheme.border
								local ret = {
										{
											self.x,
											self.y,
											self.x+self.w,
											self.y+self.h,
										},
									}
								return ret
							else
								return {}
							end
							//Desktop removal
							//return {} //Desktop removal
						end
					}
				table.insert(GM.windows,1,hack.InitWindow(self,window))
			end
		end
		*/
		
		//Warning
		if hack.focus[1] == 0 then
			self.desklight = 1
		end
		
		for i = 0,4 do
			if self.mc[i].click == -1 or self.mc[i].click == 1 then
				self.mc[i].click = 0
			end
		end
		
		self.key = {mod={},focus = self.key.focus,last=self.key.last}
		
		//Draw cursor
		surface.SetDrawColor(0,0,0,120)
		surface.DrawRect(dims.x+self.mc.x-4,dims.y+self.mc.y-4,4,4)
		surface.SetDrawColor(255,255,255,120)
		surface.DrawRect(dims.x+self.mc.x,dims.y+self.mc.y-4,4,4)
	cam.End3D2D()
end






































